/**
 *
 *  License: http://www.apache.org/licenses/LICENSE-2.0
 *  Home page: https://gitee.com/linlurui/service-abc
 *  Note: to build on java, include the jdk1.6+ compiler symbol (and yes,
 *  I know the difference between language and runtime versions; this is a compromise).
 * @author linlurui
 * @Date Date: 2020-07-07
 */

package abc.utils;

import abc.utils.jackson.ObjectMapperDateFormatExtend;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;

public class JacksonUtil
{
	private final static ObjectMapper mapper = new ObjectMapper();
	private static final Logger log = LoggerFactory.getLogger( JacksonUtil.class );

	static {
		DateFormat dateFormat = mapper.getDateFormat();
		mapper.setConfig(mapper.getDeserializationConfig().with(new ObjectMapperDateFormatExtend(dateFormat))); //反序列化扩展日期格式支持
	}

	/**
	 * json得到对象
	 * @throws IOException
	 * @throws JsonMappingException
	 * @throws JsonParseException
	 */
	public static <T> T parse( String jsonString, Class<T> pojoClass ) {
		T pojo = null;
		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		try {
			pojo = mapper.readValue( jsonString, pojoClass );
		} catch (JsonProcessingException e) {
			log.error(e.getMessage());
		}

		return pojo;
	}

	/**
	 * 集合内对象转换
	 * @throws IOException
	 * @throws JsonMappingException
	 * @throws JsonParseException
	 */
	public static <T> List<T> toList(List<?> source, Class<T> tClass) throws IOException {
		return toList(toJson(source), tClass);
	}

	/**
	 * json得到对象集合
	 * @throws IOException
	 * @throws JsonMappingException
	 * @throws JsonParseException
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static <T> List<T> toList( String json, Class<T> cls ) throws JsonParseException, JsonMappingException, IOException
	{
		ArrayList<T> mList = new ArrayList<T>();
		List array = mapper.readValue( json, List.class );
		for ( int i = 0; i < array.size(); i++ )
		{
			if(array.get( i ).getClass().equals(cls)) {
				mList.add( (T)array.get( i ) );
			}

			else {
				mList.add(JacksonUtil.convert(array.get(i), cls));
			}
		}

		return mList;
	}

	/**
	 * 获取请求体中的Json
	 */
	public static byte[] readBytes( InputStream is, int contentLen ) throws IOException
	{
		if ( contentLen > 0 )
		{
			int readLen = 0;
			int readLengthThisTime = 0;
			byte[] message = new byte[contentLen];

			while ( readLen != contentLen )
			{
				readLengthThisTime = is.read( message, readLen, contentLen - readLen );
				if ( readLengthThisTime == -1 )
				{
					break;
				}
				readLen += readLengthThisTime;
			}

			return message;

		}
		return new byte[] {};
	}

	/**
	 * obj to json
	 */
	public static String toJson( Object src )
	{
		try {
			mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
			return mapper.writeValueAsString( src );
		} catch (JsonProcessingException e) {}

		return "";
	}

	public static <T, S> T convert(S src, Class<T> pojoClass) throws IOException {
		if(src instanceof String) {
			return parse((String) src, pojoClass);
		}

		if(src.getClass().equals(pojoClass)) {
			return (T) src;
		}

		String json = toJson(src);
		T target = null;
		target = parse(json, pojoClass);

		return target;
	}
}
